#include "cx_encode_read.h"
#include "stm32f4xx_tim.h"
static cx_slist_t encoder_read_list;

#define slist_item_t2event_t(x) ((cx_encoder_read_event_t *)(x))
#define event_t2slist_item_t(x) ((cx_slist_item_t*)(x))

#define EVNET_LIST_UPDATING 0x01

cx_uint8_t flags = 0;

cx_slist_t * cx_encoder_read_init(void)
{
    cx_slist_init(&encoder_read_list);
    return &encoder_read_list;
}

cx_slist_item_t *cx_encoder_read_register(cx_encoder_read_event_t *event)
{
    cx_slist_item_t *ret;
    flags |= EVNET_LIST_UPDATING;
    ret = cx_slist_append(&encoder_read_list,event_t2slist_item_t(event));
    flags &= ~EVNET_LIST_UPDATING;

    return ret;
}

cx_slist_item_t * cx_encoder_read_delete(cx_encoder_read_event_t *event)
{
    cx_slist_item_t *ret;
    flags |= EVNET_LIST_UPDATING;
    ret = cx_slist_item_delete(&encoder_read_list, event_t2slist_item_t(event));
    flags &= ~EVNET_LIST_UPDATING;

    return ret;
}

void cx_encoder_read_cb_handler(void)
{
    cx_slist_item_t *cur = (&encoder_read_list)->head;
#define TIM_CNT (TIM6->CNT)
#define TIM_ARR (TIM6->ARR)
    if((flags & EVNET_LIST_UPDATING) == 0)
    {
        while(cur != CX_NULL)
        {
            slist_item_t2event_t(cur)->func_cb(TIM_ARR + TIM_CNT,slist_item_t2event_t(cur)->args);
            if((slist_item_t2event_t(cur)->attr & CX_ENCODER_READ_ATTR_TRIGGER_TYPE_MASK) == CX_ENCODER_READ_ATTR_TRIGGER_TYPE_ONESHOT)
            {
                cur = cx_encoder_read_delete(slist_item_t2event_t(cur));
                if(cur == CX_NULL) break;
            }
						cur = cur->next;
        }
    }
}
